package basic

import (
	"fmt"
	"reflect"
	"testing"
)

/*
测试用例统一结构
*/
type XzTestingCase struct {
	Name string
	Args KMap
	Want KMap
}

// 统一测试错误输出
func (c *XzTestingCase) Errorf(res interface{}) string {
	return fmt.Sprintf("\nCase name: %s \nArgs     : %#v\nWant     : %#v\nResult   : %#v\n", c.Name, c.Args, c.Want, res)
}

// 统一测试错误输出
func (c *XzTestingCase) Logf() string {
	return fmt.Sprintf("Case<%s> --- ok ---", c.Name)
}

// 测试逻辑类型
type XzTestingLogic func(args KMap) KMap

/*
测试逻辑统一结构
*/
type XzTesting struct {
	Cs    []XzTestingCase
	Logic XzTestingLogic
}

// 设置测试用例
func (xt *XzTesting) SetCases(cs []XzTestingCase) *XzTesting {
	xt.Cs = cs
	return xt
}

// 批量增加测试用例
func (xt *XzTesting) AppendCase(cs []XzTestingCase) *XzTesting {
	xt.Cs = append(xt.Cs, cs...)
	return xt
}

// 增加一个测试用例
func (xt *XzTesting) AddCase(c XzTestingCase) *XzTesting {
	xt.Cs = append(xt.Cs, c)
	return xt
}

// 设置计算逻辑
func (xt *XzTesting) SetLogic(logic XzTestingLogic) *XzTesting {
	xt.Logic = logic
	return xt
}

// 增加一个测试用例
func (xt *XzTesting) Done(t *testing.T) {
	for _, c := range xt.Cs {
		t.Run(c.Name, func(t *testing.T) {
			res := xt.Logic(c.Args)
			if !reflect.DeepEqual(res, c.Want) {
				t.Error(c.Errorf(res))
			} else {
				fmt.Println(c.Logf())
			}
		})
	}
}

// 创建测试逻辑
func NewTesting() *XzTesting {
	return &XzTesting{
		Cs: []XzTestingCase{},
	}
}
